package cn.edu.tju.elm.controller;

import cn.edu.tju.core.config.FileUploadConfig;
import cn.edu.tju.core.model.HttpResult;
import cn.edu.tju.core.model.ResultCodeEnum;
import cn.edu.tju.core.model.User;
import cn.edu.tju.core.security.service.UserService;
import cn.edu.tju.core.utils.FileUploadUtil;
import cn.edu.tju.elm.model.Business;
import cn.edu.tju.elm.model.Food;
import cn.edu.tju.elm.repository.BusinessRepository;
import cn.edu.tju.elm.repository.FoodRepository;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 图片上传控制器
 */
@RestController
@RequestMapping("/api/images")
@Tag(name = "图片上传", description = "提供图片上传功能")
public class ImageUploadController {

    @Autowired
    private FileUploadConfig fileUploadConfig;

    @Autowired
    private UserService userService;
    
    @Autowired
    private BusinessRepository businessRepository;
    
    @Autowired
    private FoodRepository foodRepository;

    /**
     * 上传商家图片
     *
     * @param file 上传的图片文件
     * @return 上传成功后的图片URL
     */
    @PostMapping("/business")
    @PreAuthorize("hasAnyAuthority('ADMIN', 'BUSINESS')")
    @Operation(
        summary = "上传商家图片", 
        description = "上传商家图片，需要ADMIN或BUSINESS角色权限。支持jpg、jpeg、png、gif、webp格式，文件大小限制10MB。"
    )
    @ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "上传成功", 
            content = @Content(mediaType = "application/json", 
            schema = @Schema(implementation = Map.class))),
        @ApiResponse(responseCode = "400", description = "参数错误或文件类型不支持"),
        @ApiResponse(responseCode = "401", description = "未授权"),
        @ApiResponse(responseCode = "403", description = "无权限"),
        @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public HttpResult<Map<String, String>> uploadBusinessImage(
            @Parameter(description = "要上传的图片文件", required = true) 
            @RequestParam("file") MultipartFile file,
            @RequestParam(value = "businessId", required = false) Long businessId,
            HttpServletRequest request) {
        // 获取当前登录用户
        User currentUser = userService.getUserWithAuthorities()
                .orElseThrow(() -> new AccessDeniedException("用户未登录"));

        try {
            // 上传图片
            String fileName = FileUploadUtil.saveImage(file, fileUploadConfig.getBusinessUploadDir());
            
            // 构建完整的URL（包含域名）
            String baseUrl = getBaseUrl(request);
            String imageUrl = baseUrl + fileUploadConfig.getBusinessImageUrlPrefix() + fileName;

            // 如果提供了商家ID，直接将二进制图片数据存入数据库
            if (businessId != null) {
                Optional<Business> businessOpt = businessRepository.findById(businessId);
                if (businessOpt.isPresent()) {
                    Business business = businessOpt.get();
                    
                    // 保存二进制图片数据
                    business.setBusinessImgData(file.getBytes());
                    
                    // 同时保存URL路径（兼容两种方式）
                    business.setBusinessImg(imageUrl);
                    
                    // 添加日志输出
                    System.out.println("更新商家图片 - 商家ID: " + businessId);
                    System.out.println("图片URL: " + imageUrl);
                    System.out.println("二进制数据大小: " + file.getBytes().length + " 字节");
                    
                    // 保存到数据库
                    Business updatedBusiness = businessRepository.save(business);
                    
                    // 验证保存结果
                    System.out.println("保存后的商家图片URL: " + updatedBusiness.getBusinessImg());
                    System.out.println("保存后的二进制数据是否存在: " + (updatedBusiness.getBusinessImgData() != null));
                }
            }

            // 返回图片URL
            Map<String, String> result = new HashMap<>();
            result.put("url", imageUrl);
            result.put("filename", fileName);
            return HttpResult.success(result);
        } catch (IOException e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "上传图片失败：" + e.getMessage());
        } catch (IllegalArgumentException e) {
            return HttpResult.failure(ResultCodeEnum.NOT_FOUND, "上传图片参数错误：" + e.getMessage());
        }
    }

    /**
     * 上传食品图片
     *
     * @param file 上传的图片文件
     * @return 上传成功后的图片URL
     */
    @PostMapping("/food")
    @PreAuthorize("hasAnyAuthority('ADMIN', 'BUSINESS')")
    @Operation(
        summary = "上传食品图片", 
        description = "上传食品图片，需要ADMIN或BUSINESS角色权限。支持jpg、jpeg、png、gif、webp格式，文件大小限制10MB。"
    )
    @ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "上传成功", 
            content = @Content(mediaType = "application/json", 
            schema = @Schema(implementation = Map.class))),
        @ApiResponse(responseCode = "400", description = "参数错误或文件类型不支持"),
        @ApiResponse(responseCode = "401", description = "未授权"),
        @ApiResponse(responseCode = "403", description = "无权限"),
        @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public HttpResult<Map<String, String>> uploadFoodImage(
            @Parameter(description = "要上传的图片文件", required = true) 
            @RequestParam("file") MultipartFile file,
            @RequestParam(value = "foodId", required = false) Long foodId,
            HttpServletRequest request) {
        // 获取当前登录用户
        User currentUser = userService.getUserWithAuthorities()
                .orElseThrow(() -> new AccessDeniedException("用户未登录"));

        try {
            // 上传图片
            String fileName = FileUploadUtil.saveImage(file, fileUploadConfig.getFoodUploadDir());
            
            // 构建完整的URL（包含域名）
            String baseUrl = getBaseUrl(request);
            String imageUrl = baseUrl + fileUploadConfig.getFoodImageUrlPrefix() + fileName;

            // 如果提供了食品ID，直接将二进制图片数据存入数据库
            if (foodId != null) {
                Optional<Food> foodOpt = foodRepository.findById(foodId);
                if (foodOpt.isPresent()) {
                    Food food = foodOpt.get();
                    
                    // 保存二进制图片数据
                    food.setFoodImgData(file.getBytes());
                    
                    // 同时保存URL路径（兼容两种方式）
                    food.setFoodImg(imageUrl);
                    
                    // 添加日志输出
                    System.out.println("更新食品图片 - 食品ID: " + foodId);
                    System.out.println("图片URL: " + imageUrl);
                    System.out.println("二进制数据大小: " + file.getBytes().length + " 字节");
                    
                    // 保存到数据库
                    Food updatedFood = foodRepository.save(food);
                    
                    // 验证保存结果
                    System.out.println("保存后的食品图片URL: " + updatedFood.getFoodImg());
                    System.out.println("保存后的二进制数据是否存在: " + (updatedFood.getFoodImgData() != null));
                }
            }

            // 返回图片URL
            Map<String, String> result = new HashMap<>();
            result.put("url", imageUrl);
            result.put("filename", fileName);
            return HttpResult.success(result);
        } catch (IOException e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "上传图片失败：" + e.getMessage());
        } catch (IllegalArgumentException e) {
            return HttpResult.failure(ResultCodeEnum.NOT_FOUND, "上传图片参数错误：" + e.getMessage());
        }
    }
    
    /**
     * 直接从数据库获取商家图片
     *
     * @param businessId 商家ID
     * @return 图片二进制数据
     */
    @GetMapping("/business-binary/{businessId}")
    @Operation(summary = "获取商家图片二进制数据", 
               description = "根据商家ID从数据库获取图片二进制数据")
    public ResponseEntity<byte[]> getBusinessImageBinary(@PathVariable Long businessId) {
        Optional<Business> businessOpt = businessRepository.findById(businessId);
        if (businessOpt.isPresent() && businessOpt.get().getBusinessImgData() != null) {
            Business business = businessOpt.get();
            HttpHeaders headers = new HttpHeaders();
            
            // 尝试确定图片类型
            String contentType = "image/jpeg"; // 默认JPEG
            if (business.getBusinessImg() != null) {
                String imgUrl = business.getBusinessImg().toLowerCase();
                if (imgUrl.endsWith(".png")) {
                    contentType = "image/png";
                } else if (imgUrl.endsWith(".gif")) {
                    contentType = "image/gif";
                } else if (imgUrl.endsWith(".webp")) {
                    contentType = "image/webp";
                }
            }
            
            headers.setContentType(MediaType.parseMediaType(contentType));
            // 修改缓存策略，设置为不缓存或很短时间的缓存
            headers.setCacheControl("no-cache, no-store, must-revalidate");
            headers.setPragma("no-cache");
            headers.setExpires(0);
            
            return new ResponseEntity<>(business.getBusinessImgData(), headers, HttpStatus.OK);
        } else {
            return ResponseEntity.notFound().build();
        }
    }
    
    /**
     * 直接从数据库获取食品图片
     *
     * @param foodId 食品ID
     * @return 图片二进制数据
     */
    @GetMapping("/food-binary/{foodId}")
    @Operation(summary = "获取食品图片二进制数据", 
               description = "根据食品ID从数据库获取图片二进制数据")
    public ResponseEntity<byte[]> getFoodImageBinary(@PathVariable Long foodId) {
        Optional<Food> foodOpt = foodRepository.findById(foodId);
        if (foodOpt.isPresent() && foodOpt.get().getFoodImgData() != null) {
            Food food = foodOpt.get();
            HttpHeaders headers = new HttpHeaders();
            
            // 尝试确定图片类型
            String contentType = "image/jpeg"; // 默认JPEG
            if (food.getFoodImg() != null) {
                String imgUrl = food.getFoodImg().toLowerCase();
                if (imgUrl.endsWith(".png")) {
                    contentType = "image/png";
                } else if (imgUrl.endsWith(".gif")) {
                    contentType = "image/gif";
                } else if (imgUrl.endsWith(".webp")) {
                    contentType = "image/webp";
                }
            }
            
            headers.setContentType(MediaType.parseMediaType(contentType));
            // 修改缓存策略，设置为不缓存或很短时间的缓存
            headers.setCacheControl("no-cache, no-store, must-revalidate");
            headers.setPragma("no-cache");
            headers.setExpires(0);
            
            return new ResponseEntity<>(food.getFoodImgData(), headers, HttpStatus.OK);
        } else {
            return ResponseEntity.notFound().build();
        }
    }

    /**
     * 获取基础URL，包含域名和端口
     */
    private String getBaseUrl(HttpServletRequest request) {
        String scheme = request.getScheme();
        String serverName = request.getServerName();
        int serverPort = request.getServerPort();
        
        // 构建基础URL
        StringBuilder url = new StringBuilder();
        url.append(scheme).append("://").append(serverName);
        
        // 添加非标准端口
        if (serverPort != 80 && serverPort != 443) {
            url.append(":").append(serverPort);
        }
        
        return url.toString();
    }
} 